<template>
	<div>
		<!-- 顶部工具栏 -->
		<el-row type="flex" justify="end">
			<el-col :span="22">
				<el-button
					type="danger"
					size="small"
					v-show="multipleSelection.length > 0"
					@click="handleMultipleDelete"
				>批量删除</el-button>
			</el-col>
			<el-col :span="2" class="col-add">
				<el-button type="primary" size="small" @click="handleAddClick">添加</el-button>
			</el-col>
		</el-row>
		<!-- 表格区域 -->
		<el-table
			ref="multipleRoomTypeTable"
			:data="bedRoomTypes"
			tooltip-effect="dark"
			style="width: 100%"
			@selection-change="handleSelectionChange"
		>
			<el-table-column type="selection" width="55"></el-table-column>
			<el-table-column type="expand">
				<template v-slot="scope">
					<el-row>
						<el-col :span="12">{{scope.row}}</el-col>
						<el-col :span="12"></el-col>
					</el-row>
				</template>
			</el-table-column>
			<el-table-column label="房型名称" prop="title">
				<template v-slot="scope">
					<el-input
						v-model="scope.row.title"
						@blur="roomTypeInputBlur(scope.row)"
						@change="isRoomPropInputChanged = true"
					/>
				</template>
			</el-table-column>
			<el-table-column label="英文名称-单数" prop="singularTitle_en">
				<template v-slot="scope">
					<el-input
						v-model="scope.row.singularTitle_en"
						@blur="roomTypeInputBlur(scope.row)"
						@change="isRoomPropInputChanged = true"
					/>
				</template>
			</el-table-column>
			<el-table-column label="英文名称-复数" prop="pluralTitle_en">
				<template v-slot="scope">
					<el-input
						v-model="scope.row.pluralTitle_en"
						@blur="roomTypeInputBlur(scope.row)"
						@change="isRoomPropInputChanged = true"
					/>
				</template>
			</el-table-column>
			<el-table-column label="操作" width="180px">
				<template slot-scope="scope">
					<el-tooltip class="item" effect="dark" content="添加子房型项" placement="top">
						<el-button
							type="primary"
							icon="el-icon-plus"
							size="mini"
							@click="handleAddChildrenClick(scope.row)"
						/>
					</el-tooltip>
					<el-tooltip class="item" effect="dark" content="编辑匹配项" placement="top">
						<el-button
							type="warning"
							icon="el-icon-setting"
							size="mini"
							@click="handleEditMatchesClick(scope.row)"
						/>
					</el-tooltip>
					<el-tooltip class="item" effect="dark" content="删除" placement="top">
						<el-button
							type="danger"
							icon="el-icon-delete"
							size="mini"
							@click="handleDelete(scope.row._id)"
						/>
					</el-tooltip>
				</template>
			</el-table-column>
		</el-table>
		<!-- 添加/编辑房型弹出面板 -->
		<el-dialog
			:title="roomDialogTitle"
			:visible.sync="roomTypeDialogVisible"
			@closed="handleRoomTypeDialogClosed"
		>
			<el-form :model="roomType" :rules="roomTypeRules" ref="roomFormRef" label-width="120px">
				<el-form-item label="房型名称" prop="title">
					<el-input v-model="roomType.title" autocomplete="off" />
				</el-form-item>
				<el-form-item label="英文名称-单数" prop="singularTitle_en">
					<el-input v-model="roomType.singularTitle_en" autocomplete="off" />
				</el-form-item>
				<el-form-item label="英文名称-复数" prop="pluralTitle_en">
					<el-input v-model="roomType.pluralTitle_en" autocomplete="off" />
				</el-form-item>
			</el-form>
			<div slot="footer" class="dialog-footer">
				<el-button @click="roomTypeDialogVisible = false">取 消</el-button>
				<el-button type="primary" @click="handleRoomTypeDialogConfirmClick">确 定</el-button>
			</div>
		</el-dialog>
		<!-- 编辑匹配项弹出面板 -->
		<el-dialog title="编辑匹配项" :visible.sync="matchesDialogVisible" width="50%" @closed="matches = []">
			<!-- 顶部工具栏 -->
			<el-row type="flex" justify="end" align="middle">
				<el-col :span="1">
					<el-checkbox
						v-model="ismatchesAllSelected"
						v-show="isMatchesConfirmDeleteVisible"
						:indeterminate="ismatchesIndeterminated"
						@change="handleMultipleMatchesToggleClick"
					/>
				</el-col>
				<el-col :span="21">
					<el-button
						type="danger"
						size="small"
						v-show="matches.length > 0"
						:disabled="isMatchesDeleteButtonVisible"
						@click="handleMultipleMatchDeleteClick"
					>{{matchesDeleteButtonText}}</el-button>
				</el-col>
				<el-col :span="2" class="col-add">
					<el-button type="primary" size="small" @click="handleMatchAddClick">添加</el-button>
				</el-col>
			</el-row>
			<!-- 列表区域 -->
			<!-- 列表为空时 -->
			<h3 v-if="matches.length < 1" style="text-align: center;">当前匹配项列表为空</h3>
			<!-- 列表不为空 -->
			<div class="list-matches" v-else>
				<el-row
					v-for="(item, index) in matches"
					:key="index"
					:gutter="5"
					type="flex"
					align="middle"
					justify="space-between"
				>
					<!-- 为了每行的三个控件受父级el-row的flex控制，呈现垂直居中效果，必须保证在同一个el-col中 -->
					<el-checkbox
						v-model="item.selected"
						v-show="isMatchesConfirmDeleteVisible"
						@change="handleToggleMatch"
					></el-checkbox>
					<el-input v-model="item.value" class="input-match" />
					<el-button type="danger" size="mini" icon="el-icon-delete" @click="handleDeleteMatch(index)"></el-button>
				</el-row>
			</div>
			<div slot="footer" class="dialog-footer">
				<el-button @click="matchesDialogVisible = false">取 消</el-button>
				<el-button type="primary" @click="handleEditMatchesConfirmClick">确 定</el-button>
			</div>
		</el-dialog>
		<!-- 添加子房型项弹出面板 -->
		<el-dialog
			title="添加子房型项"
			:visible.sync="isChildrenDialogVisible"
			width="30%"
			@close="handleChildrenDialogClosed"
		>
			<el-form :model="childrenItem" :rules="childrenRules" ref="childrenFormRef" label-width="80px">
				<el-form-item label="子房型" prop="type">
					<el-select v-model="childrenItem.type" placeholder="请选择">
						<el-option v-for="type in bedRoomTypes" :key="type._id" :label="type.title" :value="type._id"></el-option>
					</el-select>
				</el-form-item>
				<el-form-item label="数量" prop="count">
					<el-input v-model.number="childrenItem.count" />
				</el-form-item>
			</el-form>

			<span slot="footer">
				<el-button @click="isChildrenDialogVisible = false">取 消</el-button>
				<el-button type="primary" @click="handleChildrenDialogConfirmClick">确 定</el-button>
			</span>
		</el-dialog>
	</div>
</template>

<script>
	import _ from "lodash";
	import roomTypeRules from "./form-rules/roomTypeRules";
	import childrenRules from "./form-rules/childrenRules";

	export default {
		name: "room-types-list",
		data() {
			return {
				// 房型列表-非床位类型
				roomTypes: [],
				// 房型列表-床位类型
				bedRoomTypes: [],
				isRoomPropInputChanged: false,
				// 房型列表的多选列表
				multipleSelection: [],
				// 标识添加/编辑房型弹出框是否可见
				roomTypeDialogVisible: false,
				// 标识编辑房型匹配项弹出框是否可见
				matchesDialogVisible: false,
				// 编辑房型匹配项每个表单项左列标题标签的宽度
				formLabelWidth: "120px",
				// 将被添加/编辑的房型对象
				roomType: {
					title: "",
					singularTitle_en: "",
					pluralTitle_en: "",
					// 标识是否为床位房型，不可删除，此页面仅操作床位房型
					isBed: true
				},
				// 将被编辑的房型匹配项列表
				// 注意：不能直接绑定房型对象中的matches数组对象，因为没有深度监听，不能同步数据
				matches: [],
				// 标识当前需要添加还是编辑房型对象
				isAddingMode: true,
				// 是否显示CheckBox列
				isMatchesConfirmDeleteVisible: false,
				// 标识是否所有匹配项都被选中
				ismatchesAllSelected: false,
				// 标识是否被选中的匹配项数量大于0且并未全选
				ismatchesIndeterminated: false,
				// 添加/编辑房型的表单验证规则
				roomTypeRules,
				// 添加子房型项的表单验证规则
				childrenRules,
				// 标识添加子房型项弹出面板是否可见
				isChildrenDialogVisible: false,
				childrenItem: {
					type: null,
					count: 1
				}
			};
		},
		created() {
			this.getRoomTypes();
			this.getBedRoomTypes();
		},
		computed: {
			matchesDeleteButtonText: function() {
				return this.isMatchesConfirmDeleteVisible ? "确认删除" : "批量删除";
			},
			isMatchesDeleteButtonVisible: function() {
				return (
					this.isMatchesConfirmDeleteVisible &&
					!this.ismatchesAllSelected &&
					!this.ismatchesIndeterminated
				);
			},
			roomDialogTitle: function() {
				return this.isAddingMode ? "添加房型" : "编辑房型";
			}
		},
		methods: {
			// 获取所有房型列表
			async getRoomTypes() {
				const res = await this.$http.get("/room-types");
				this.roomTypes = res || [];
			},
			// 获取所有子房型列表
			async getBedRoomTypes() {
				this.bedRoomTypes =
					(await this.$http.get("/room-types?isBed=true")) || [];
			},
			// 发送添加/编辑房型请求
			async sendRoomTypeRequest() {
				const method = this.isAddingMode ? "post" : "put";
				const url = this.isAddingMode
					? "/room-types"
					: `/room-types/${this.roomType._id}`;
				await this.$http[method](url, this.roomType, true);
				this.getRoomTypes();
			},
			// 发送删除房型的请求
			async deleteRoomTypeByID(id) {
				this.$confirm("此操作不可恢复, 是否确认删除?", "提示", {
					confirmButtonText: "确定",
					cancelButtonText: "取消",
					type: "warning"
				})
					.then(async () => {
						await this.$http.delete(`/room-types/${id}`, null, true);
						this.getRoomTypes();
					})
					.catch(() => {
						this.$message({
							type: "info",
							message: "已取消删除"
						});
					});
			},
			// 房型列表项的输入框失去焦点事件-提交房型信息更改
			roomTypeInputBlur(roomType) {
				if (this.isRoomPropInputChanged) {
					this.isRoomPropInputChanged = false;
					this.isAddingMode = false;
					this.roomType = roomType;
					this.sendRoomTypeRequest();
				}
			},
			// 全选/全不选
			toggleSelection(rows) {
				if (rows) {
					rows.forEach(row => {
						this.$refs.multipleTable.toggleRowSelection(row);
					});
				} else {
					this.$refs.multipleTable.clearSelection();
				}
			},
			// 单个CheckBox状态切换
			handleSelectionChange(val) {
				this.multipleSelection = val;
			},
			// 打开房型弹出框，并设置为添加房型模式
			handleAddClick() {
				this.isAddingMode = true;
				this.roomTypeDialogVisible = true;
			},
			// 确认添加房型
			async handleRoomTypeDialogConfirmClick() {
				await this.sendRoomTypeRequest();
				this.roomTypeDialogVisible = false;
			},
			// 房型弹出框关闭事件
			handleRoomTypeDialogClosed() {
				this.$refs.roomFormRef.resetFields();
			},
			// 删除指定房型-带确认框
			handleDelete(id) {
				this.deleteRoomTypeByID(id);
			},
			// 删除所有房型-带确认框
			handleMultipleDelete() {
				const idStr = this.multipleSelection
					.map(item => item._id)
					.join("-");
				this.deleteRoomTypeByID(idStr);
			},
			// 弹出编辑匹配项的面板
			handleEditMatchesClick(roomType) {
				// 设置为编辑模式，否则报错
				this.isAddingMode = false;
				// 初始化CheckBox选中状态
				this.isMatchesConfirmDeleteVisible = false;
				this.ismatchesIndeterminated = false;
				this.ismatchesAllSelected = false;
				// 改变当前编辑的房型及房型匹配项列表
				this.roomType = roomType;
				this.matches = roomType.matches.map(match => ({
					value: match,
					selected: false
				}));
				this.matchesDialogVisible = true;
			},
			// 确认保存匹配项更改
			handleEditMatchesConfirmClick() {
				this.matchesDialogVisible = false;
				this.roomType.matches = this.matches.map(match => match.value);
				this.sendRoomTypeRequest();
			},
			// 删除匹配项
			handleDeleteMatch(index) {
				this.matches.splice(index, 1);
				// 删除后更改涉及到的CheckBox的状态
				this.handleToggleMatch();
			},
			// 批量删除房型匹配项
			handleMultipleMatchDeleteClick() {
				if (this.isMatchesConfirmDeleteVisible) {
					this.matches = this.matches.filter(match => !match.selected);
				}
				// 显示按钮和确认删除按钮共用一个控件，仅调整显示文字和状态
				this.isMatchesConfirmDeleteVisible = !this
					.isMatchesConfirmDeleteVisible;
			},
			// 添加房型匹配项
			handleMatchAddClick() {
				const matches = this.matches;
				if (matches) {
					const hasNoEmpty =
						matches.findIndex(item => item.value === "") < 0;
					hasNoEmpty &&
						matches.unshift({
							value: "",
							selected: false
						});
				} else {
					matches = [{ value: "", selected: false }];
				}
			},
			// 单个房型匹配项选中状态更改
			handleToggleMatch() {
				const totalLength = this.matches.length;
				const selectedLength = this.matches.filter(match => match.selected)
					.length;
				this.ismatchesAllSelected =
					totalLength > 0 && totalLength === selectedLength;
				this.ismatchesIndeterminated =
					totalLength > 0 &&
					!this.ismatchesAllSelected &&
					selectedLength > 0;
				if (totalLength < 1) {
					this.isMatchesConfirmDeleteVisible = false;
				}
			},
			// 全选/全不选房型匹配项选中状态更改
			handleMultipleMatchesToggleClick(value) {
				this.ismatchesAllSelected = value;
				this.matches.forEach(match => (match.selected = value));
				this.ismatchesIndeterminated = false;
				if (this.matches.length < 1) {
					this.isMatchesConfirmDeleteVisible = false;
				}
			},
			// 打开房型弹出框，并设置为编辑房型模式
			handleAddChildrenClick(roomType) {
				this.isAddingMode = false;
				this.roomType = roomType;
				this.isChildrenDialogVisible = true;
			},
			handleChildrenDialogClosed() {
				this.$refs.childrenFormRef.resetFields();
			},
			handleChildrenDialogConfirmClick() {
				this.roomType.children.push(_.cloneDeep(this.childrenItem));
				this.isAddingMode = false;
				this.sendRoomTypeRequest();
			}
		}
	};
</script>
<style lang="scss">
	.col-add {
		display: flex;
		justify-content: flex-end;
	}
	.list-matches {
		padding: 10px;
		max-height: 320px;
		overflow: hidden auto;
		// border: 1px solid #eee;
		.input-match {
			margin: 0 10px;
		}
	}
</style>